package rensoft.android.json;

import org.json.JSONException;
import org.json.JSONTokener;

import static rensoft.java.lang.Lang.exception;
import static rensoft.java.lang.Lang.unexpected;

import rensoft.java.json.JSON;
import rensoft.java.json.JSONArray;
import rensoft.java.json.JSONBoolean;
import rensoft.java.json.JSONContainer;
import rensoft.java.json.JSONNumber;
import rensoft.java.json.JSONObject;
import rensoft.java.json.JSONString;
import rensoft.java.json.JSONType;

public class JSONImpl implements JSON {

  public static JSONType create(Object value) {
    if (value instanceof org.json.JSONObject)
      return new JSONObjectImpl((org.json.JSONObject) value);
    if (value instanceof org.json.JSONArray) return new JSONArrayImpl((org.json.JSONArray) value);
    if (value instanceof Boolean)
      return JSONBooleanImpl.getInstance(((Boolean) value).booleanValue());
    if (value instanceof String) return new JSONStringImpl((String) value);
    if (value instanceof Integer) return new JSONNumberImpl((Integer) value);
    if (value instanceof Long) return new JSONNumberImpl((Long) value);
    if (value instanceof Double) return new JSONNumberImpl((Double) value);
    throw unexpected("Should we implement null?");
  }

  public JSONBoolean create(boolean value) {
    return JSONBooleanImpl.getInstance(value);
  }

  public JSONNumber create(double number) {
    return new JSONNumberImpl(number);
  }

  public JSONString create(String value) {
    return new JSONStringImpl(value);
  }

  public JSONArray createArray() {
    return new JSONArrayImpl();
  }

  public JSONObject createObject() {
    return new JSONObjectImpl();
  }

  public JSONContainer parse(String json) {
    try {
      return create(new JSONTokener(json).nextValue()).asContainer();
    } catch (JSONException e) {
      throw exception(e);
    }
  }
}
